﻿using System.Collections;

using UnityEngine;

namespace Assets.XyzCode.Fight.Game.Enemy
{
    partial class Enemy_X_Behav
    {
        /** 击飞携程 */
        private Coroutine _doHitAway_XC = null;

        /// <summary>
        /// 执行被击飞
        /// </summary>
        /// <param name="angle">角度, 也就是与地面的夹角</param>
        /// <param name="strength">力量强度, 强度越大飞的越高或者越远</param>
        public void DoHitAway(float angle, float strength)
        {
            if (!CanSwitchStateTo(StateEnum.HitAway))
            {
                return;
            }

            if (null != _doHitAway_XC)
            {
                StopCoroutine(_doHitAway_XC);
            }

            StopRun();

            _currState = StateEnum.HitAway;
            _doHitAway_XC = StartCoroutine(DoHitAway_XC(angle, strength));
        }

        /// <summary>
        /// ( 携程方式 ) 执行被击飞
        /// </summary>
        /// <param name="angle">角度, 也就是与地面的夹角, 取值范围 0 ~ 180 </param>
        /// <param name="strength">力量强度, 强度越大飞的越高或者越远</param>
        /// <returns>枚举迭代器</returns>
        private IEnumerator DoHitAway_XC(float angle, float strength)
        {
            if (strength <= 0 
             || null == _VIEW)
            {
                yield break;
            }

            // 起飞之前先迅速腾空并停留一下会儿
            transform.position += Vector3.up;

            float pauseTime = 0.05f;

            while (pauseTime > 0)
            {
                pauseTime -= Time.deltaTime;
                yield return 1;
            }

            // 角度必须是正数, 
            // 且必须在 0 ~ 180 之间
            angle = Mathf.Abs(angle) % 180f;

            // 播放摔倒动画
            PlayDBAnim(GetFall_X_Anim(angle), 1);

            // 计算 X 轴和 Y 轴上的速度
            float vx = strength * Mathf.Cos(angle / 180.0f * Mathf.PI);
            float vy = strength * Mathf.Sin(angle / 180.0f * Mathf.PI);
            // 初始化重力影响
            float sumG = 40f;

            for (int i = 0; ; i++)
            {
                if (i > 0
                 && transform.position.y <= 0f)
                {
                    break;
                }

                // 变化时间
                float deltaT = Time.deltaTime;
                // 持续增加重力影响
                sumG += 9.8f * deltaT;
                vy -= sumG * deltaT;

                // XXX 注意: 重力加速度 G = 9.8 米 / 秒 ^ 2,
                // 那么瞬时产生的加速度 Vt = G * (t1 - t0),
                // 这个速度需要叠加在原始速度上...
                // 最后, 我们再用 Y 速度减掉这个叠加后的速度就得到当前速度!
                // 这里得通过画图来说明. 

                transform.position +=
                    Vector3.right * vx * deltaT +
                       Vector3.up * vy * deltaT;

                yield return 1;
            }

            transform.position = new Vector3(
                transform.position.x, 0, transform.position.z
            );

            // 倒地之后先躺一会儿
            yield return new WaitForSeconds(Random.Range(-2f, 2f) + 5f);

            _doHitAway_XC = null;
            yield break;
        }

        /// <summary>
        /// 获取摔倒动画
        /// </summary>
        /// <param name="angle">角度</param>
        /// <returns>动画名称</returns>
        private string GetFall_X_Anim(float angle)
        {
            if (Mathf.Abs(Quaternion.Angle(transform.localRotation, FACE_TO_R)) <= 10f)
            {
                // 
                // 这里需要考虑角度误差, 出入是在 10 度以内, 
                // 则说明角色是面向右站立的...
                // 如果角色脸朝右
                // 
                if (angle < 90)
                {
                    // 向右飞
                    return "Fall_1";
                }
                else
                {
                    // 向左飞
                    return "Fall_0";
                }
            }
            else
            {
                // 如果角色脸朝左
                // 
                if (angle < 90)
                {
                    // 向左飞
                    return "Fall_0";
                }
                else
                {
                    // 向右飞
                    return "Fall_1";
                }
            }
        }
    }
}
